package org.deng.vertx.core;

import io.vertx.core.*;
import io.vertx.core.file.FileProps;
import io.vertx.core.file.FileSystem;
import io.vertx.core.json.JsonObject;

/**
 * @author Libin.Deng
 * @date 2021/8/22 18:44
 * @desc
 */
public class Main {
    public static void main(String[] args) throws InterruptedException {
        deployVerticle();
        //futureResults();
    }

    /**
     * 部署Verticle
     * 这儿有两种 Verticle：
     *
     * Standard Verticles
     * 这是最常用的一类 Verticle —— 它们永远运行在 Event Loop 线程上。
     *
     * Worker Verticles
     * 这类 Verticle 会运行在 Worker Pool 中的线程上。 一个实例绝对不会被多个线程同时执行
     */
    private static void deployVerticle(){
        //默认情况一个 Vert.x 实例维护了N个 Event Loop 线程（默认情况下N = CPU核数 x 2）
        Vertx vertx = Vertx.vertx(new VertxOptions()
                .setWorkerPoolSize(8) //工作线程数
                .setEventLoopPoolSize(4) //事件循环线程数
        );
        // 部署参数
        //使用名称部署 Verticle 时，可以指定需要部署的 Verticle 实例的数量。
        //这个功能对于跨多核扩展时很有用。例如，您有一个带Web服务的Verticle需要部署在多核的机器上， 您可以部署多个实例来利用所有的核。
        DeploymentOptions options = new DeploymentOptions();
        options.setInstances(2); // 实例数
        //添加自定义配置，在verticle中 config().getString("name")
        JsonObject config = new JsonObject().put("name", "tim").put("directory", "/blah");
        options.setConfig(config);
        //一个应用程序通常是由在同一个 Vert.x 实例中同时运行的许多 Verticle 实例组合而成。
        // 不同的 Verticle 实例通过向 Event Bus 上发送消息来相互通信。
        vertx.deployVerticle(MyFirstVerticle.class.getName(), options);
    }

    /**
     * 回调结果
     */
    private static void futureResults() throws InterruptedException {
        Vertx vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(10));
        FileSystem fileSystem = vertx.fileSystem();

        //内部在工作线程中（线程池）执行读取文件属性的任务，任务读取完成后，获取到结果（成功或失败），并保存的future对象中,
        //然后获取监听器，如果监听器不为空，则在事件循环线程中执行监听器中的方法（成功或失败）
        Future<FileProps> future = fileSystem.props("C:\\Users\\mdjro\\Desktop\\my.txt");

        System.out.println("Set OnComplete1");
        //内部注册一个监听器,任务成功或失败都会调用handle方法
        //注册监听器（监听器为空则直接赋值给监听器，如果不为空，则创建一个监听器集合把原来的和新加入的都加入到监听器集合中），
        // 如果任务已经完成（future中的结果不为空），
        // 如果结果是成功，则会在事件循环线程中执行监听器的成功回调，
        // 如果结果是失败，则会在事件循环线程中执行监听器的失败回调
        future.onComplete(new Handler<AsyncResult<FileProps>>() {
            @Override
            public void handle(AsyncResult<FileProps> ar) {
                System.out.println("Complete1:"+Thread.currentThread().getName());
            }
        });

        System.out.println("Set OnComplete1 done");

        System.out.println("Set OnComplete2");

        future.onComplete((AsyncResult<FileProps> ar)->{
            System.out.println("Complete2:"+Thread.currentThread().getName());
            if (ar.succeeded()) {
                FileProps props = ar.result();
                System.out.println("File size = " + props.size());
            } else {
                System.out.println("Failure: " + ar.cause().getMessage());
            }
        });
        System.out.println("Main Ok");
    }
}
